/*! \file
 * \brief Implementation file for the file-output.
 * \author Ivo Wingelaar
 * \date 2011
 * \version 0.1.0
 * \copyright GNU Lesser General Public License v3
 */

#include "MythFile_OutputFile_C.hpp"

namespace Myth
{
namespace File
{

//! Creates an output to a file.
/*!
 * \param[in] stream_name Name of the stream.
 * \param[in] file_name Path to the file you want to open for writing.
 * \param[in] append If true and the file already exists, any data written will be appended to it, otherwise it will create a new file.
 */
OutputFile_C::OutputFile_C(const std::string& stream_name, const std::string& file_name, bool append) :
    Output(stream_name),
    mFileName(file_name),
    mFile(0)
{
    open_file(append);
}

//! Virtual destructor.
OutputFile_C::~OutputFile_C(void)
{
    if(mFile != NULL)
        fclose(mFile);
}

//! Writes a number of bytes to an output.
/*!
 * \return The number of bytes written.
 * \param[in] buffer The data to write.
 * \param[in] size The size of the data you want to write.
 * \throw OutputException if something went wrong.
 */
uintptr_t OutputFile_C::write(const void* buffer, uintptr_t size)
{
    return (int32_t)fwrite(buffer, 1, size, mFile);
}

//! Changes the position in the data-output.
/*!
 * \return If the specifief position was reached true is returned, false otherwise.
 * \param[in] position The position you want to seek to.
 * \param[in] relative Should we change the position relative to this, or absolute?
 */
bool OutputFile_C::seek(uintptr_t position, bool relative)
{
    return (fseek(mFile, position, relative ? SEEK_CUR : SEEK_SET) == 0);
}

//! Returns the current position of the input.
/*!
 * \return The current position of the input.
 */
uintptr_t OutputFile_C::get_pos(void) const
{
    return (uintptr_t)ftell(mFile);
}

//! Return if the file was opened succesfuly
/*!
 * \return True if the file was opened, false otherwise.
 */
bool OutputFile_C::is_open(void) const
{
    return (mFile != NULL);
}

//! Tries to open the file.
/*!
 * \param[in] append True if you want to append to the file, false otherwise.
 */
void OutputFile_C::open_file(bool append)
{
    if(mFileName.size() == 0)
    {
        mFile = NULL;
        return;
    }

    mFile = fopen(mFileName.c_str(), append ? "ab" : "wb");
}

} // namespace File
} // namespace Myth
